package main

import (
    "os"
	"log"
	"io"
	"bufio"
	"strings"
)

type stringMap map[string]string

type configIni struct {
	config map[string]stringMap
}

const (
	LINE_BREAK = '\n'
	CONFIG_DELIM = "="
	SECTION_LEFT_DELIM = '['
	SECTION_RIGHT_DELIM = ']'
	SLICE_DEFAULT_SIZE = 512
)

func init() {
	log.SetFlags(log.Lshortfile);
}

func main() {
	if len(os.Args) < 2 {
		log.Fatal("please input [./command] [filename]")
	}
	readContent, readFileError := ReadFile(os.Args[1])
	if readFileError != nil {
		log.Fatal(readFileError.Error())
	}
	
	config := NewConfig()
	config.ReadSection(readContent, "")
	log.Println(config)
}


//init configIni
func NewConfig() (*configIni) {
	return &configIni{make(map[string]stringMap)}
}

//extend string slice space
func extendStringSlice(s *[]string, size int) () {
	if size == len(*s) {
		newSlice := make([]string, size + size * 2)
		copy(newSlice, *s)
		*s = newSlice
	}
}

//read file
func ReadFile(filename string) ([]string, error) {
	fd, pathError := os.Open(filename)
	if pathError != nil {
		return nil, pathError 	
	}
	defer fd.Close()

	reader := bufio.NewReader(fd)
	lines := make([]string, SLICE_DEFAULT_SIZE) 
	i := 0
	for line, err := reader.ReadString(LINE_BREAK); err != io.EOF; line, err = reader.ReadString(LINE_BREAK) {
		if err != nil {
			return nil, err
		}
			
		if i >= SLICE_DEFAULT_SIZE {
			extendStringSlice(&lines, i)	
		}
		lines[i] = line
		i++
	}	
	return lines[0:i], nil	
}


//read section
func ( self *configIni)ReadSection(datas []string, sectionName string) {
	var dataLen int
	for i, data := range datas {
		dataLen = len(data)
		if data[0] == SECTION_LEFT_DELIM && data[dataLen - 2] == SECTION_RIGHT_DELIM {
			sectionName = data[1:dataLen - 2]
			self.config[sectionName] = make(stringMap)
			self.ReadSection(datas[i+1:], sectionName)
		} else if  _, ok := self.config[sectionName]; ok {
			if kv := strings.Split(data, CONFIG_DELIM); len(kv) == 2 {
				self.config[sectionName][kv[0]] = kv[1]
			}	
		}		
	}
}